home *** CD-ROM | disk | FTP | other *** search
- IDEAL
- NOJUMPS
- SMART
-
- P386 ; Use 386 instructions
-
- MODEL medium
-
- EXTRN _Points:word, _Passes:word, _BitReversed:word, _SinTable:word
-
- CODESEG
-
- ;
- ; void RealFFT(int near *DataTable);
- ;
- PROC C RealFFT
- PUBLIC RealFFT
- ARG DataTable:word
- LOCAL sptr:word,But_per_group:word,twiddle:word
- LOCAL Endptr1:word,Endptr2:word,Sval:dword,Cval:dword
- LOCAL HRplus:dword,HRminus:dword,HIplus:dword,HIminus:dword
- USES SI,DI
-
- mov ax,[DataTable]
- mov bx,[_Points]
- shl bx,1
- add ax,bx
- mov [Endptr1],ax ; Point to end of buffer (begin+points*2)
-
- shr bx,1 ; Butterflies for 1st pass=(Points/4) (*4 for indexing pairs of ints)
-
- ;
- ; Beginning of a new pass through the data
- ;
-
- Pass:
- mov si,[DataTable]
- mov di,si
- add di,bx
- mov [But_per_group],bx ; save this value for later
-
- mov bx,[_SinTable]
- mov [sptr],bx
-
- ;
- ; Beginning of a new group (groups all use the same sin/cos values)
- ;
-
- Set:
- mov bx,[sptr]
- add [sptr],4
- movsx ecx,[word ptr bx] ; sin is always in ECX
- movsx edx,[word ptr bx+2] ; cos is always in EDX
-
- mov [Endptr2],di ; End pointer for this group
-
- ;
- ; Beginning of a Butterfly
- ;
-
- Butterfly:
- movsx eax,[word ptr di] ; Get Br
- movsx ebx,[word ptr di+2] ; Get Bi
- imul eax,edx
- imul ebx,ecx
- add eax,ebx
- movsx ebx,[word ptr si] ; Get Ar
- sar eax,15 ; v1 = Br*cos + Bi*sin
- sub ebx,eax
- sar ebx,1
- mov [si],bx ; Ar = Ar - v1
- add ebx,eax
- movsx eax,[word ptr di] ; Get Br
- mov [word ptr di],bx ; Br = Ar + v1
-
- movsx ebx,[word ptr di+2] ; Get Bi
- imul eax,ecx
- imul ebx,edx
- sub eax,ebx
- movsx ebx,[word ptr si+2] ; Get Ai
- sar eax,15 ; v2 = Br*sin - Bi*cos
- sub ebx,eax
- sar ebx,1
- mov [di+2],bx ; Bi = Ai - v2
- add ebx,eax
- mov [si+2],bx ; Ai = Ai + v2
-
- add si,4
- add di,4
-
- ;
- ; End of Butterfly
- ;
-
- cmp si,[Endptr2]
- jb short Butterfly
-
- mov si,di
- add di,[But_per_group]
-
- ;
- ; End of Group
- ;
-
- cmp si,[Endptr1]
- jb short Set
-
- ;
- ; End of Pass
- ;
-
- mov bx,[But_per_group]
- shr bx,1
- cmp bx,2
- jne Pass
-
- ;
- ; Reconstruct the output for the real input
- ;
-
- mov bx,[DataTable]
- movsx eax,[word ptr bx] ; Handle bin 0 case special
- movsx ecx,[word ptr bx+2]
- add eax,ecx
- mov [bx],ax
- mov [word ptr bx+2],0
-
- mov si,[_BitReversed] ; Set up index pointers
- add si,2
- mov di,[_Points]
- add di,si
- sub di,4
- Loopit:
- mov bx,[di] ; Point to Hr(N-n)
- add bx,bx ; Double it for integers
- add bx,[DataTable]
-
- movsx eax,[word ptr bx] ; Get Hr(N-n)
- movsx ecx,[word ptr bx+2] ; Get Hi(N-n)
-
- mov bx,[si] ; Point to Hr(n)
- add bx,bx ; Double it for integers
-
- add bx,[_SinTable]
- movsx edx,[word ptr bx]
- mov [Sval],edx
- movsx edx,[word ptr bx+2]
- mov [Cval],edx
-
- sub bx,[_SinTable]
- add bx,[DataTable]
- movsx edx,[word ptr bx+2] ; Get Hi(n)
-
- sub edx,ecx ; edx=Hi(n)-Hi(N-n)
- sal ecx,1
- add ecx,edx ; ecx=Hi(n)+Hi(N-n)
-
- mov [HIminus],edx
- mov [HIplus],ecx
-
- movsx edx,[word ptr bx] ; Get Hr(n)
-
- sub edx,eax ; edx=Hr(n)-Hr(N-n)
- sal eax,1
- add eax,edx ; eax=Hr(n)+Hr(N-n)
-
- mov [HRminus],edx
-
- imul ecx,[Cval] ; Multiply Hi+ by (-COS)
- imul edx,[Sval] ; Multiply Hr- by (-SIN)
- sub ecx,edx
- sar ecx,15
-
- sub eax,ecx ; eax=(Hr+) - (Hi+)(-COS) + (Hr-)(-SIN)
- sar eax,1 ; *0.5
- add ecx,eax ; ecx=(Hr+) + (Hi+)(-COS) - (Hr-)(-SIN)
- ; *0.5
-
- mov [bx],ax ; Save Fr(n)
-
- mov eax,[HIplus]
- imul eax,[Sval]
-
- mov edx,[HRminus]
- imul edx,[Cval]
- add eax,edx
- sar eax,15
-
- mov edx,[HIminus]
-
- sub eax,edx ; eax=(-(Hi-) + (Hr-)(-COS) + (Hi+)(-SIN))
- sar eax,1 ; *0.5
- add edx,eax ; edx=( (Hi-) + (Hr-)(-COS) + (Hi+)(-SIN)) *0.5
-
- mov [bx+2],dx ; Save Fi(n)
-
- mov bx,[di] ; Point to Hr(N-n)
- add bx,bx ; Double it for integers
- add bx,[DataTable]
- mov [bx],cx ; Save Fr(N-n)
- mov [bx+2],ax ; Save Fi(N-n)
-
- add si,2
- sub di,2
- cmp si,di
- jbe Loopit
-
- ret
-
- ENDP RealFFT
-
- end
-